package objects;

import static objects.AdapletConstants.sNewLine;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.LinkedHashMap;
import java.util.Map;

import sections.ISection.Section;

public class Interface implements IObject
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 2662518774728632697L;
	private String fInterfaceName;
	private String fTableName;
	private String fBaseObject;
	private String fBaseObjectColumn;

	private Map<String, String> fAttributeList;

	public Interface()
	{
		fInterfaceName = "";
		fTableName = "";
		fBaseObject = "";
		fBaseObjectColumn = "";

		fAttributeList = new LinkedHashMap<String, String>();
	}

	public String getBaseObjectColumn()
	{
		return fBaseObjectColumn;
	}

	public void setBaseObjectColumn(String baseObjectColumn)
	{
		this.fBaseObjectColumn = baseObjectColumn;
	}

	public void setInterfaceName(String interfaceName)
	{
		fInterfaceName = interfaceName;
	}

	public String getInterfaceName()
	{
		return fInterfaceName;
	}

	public void setTableName(String tableName)
	{
		fTableName = tableName;
	}

	public String getTableName()
	{
		return fTableName;
	}

	public void setBaseObject(String baseObject)
	{
		fBaseObject = baseObject;
	}

	public String getBaseObject()
	{
		return fBaseObject;
	}

	public void addAttribute(String attrName, String colName)
	{
		fAttributeList.put(attrName, colName);
	}

	@Override
	public String toString()
	{
		return buildInterfaceDefinition();
	}

	public String buildInterfaceDefinition()
	{
		StringBuffer interfaceDef = new StringBuffer(500);

		interfaceDef.append("interface \"");
		interfaceDef.append(fInterfaceName);
		interfaceDef.append("\" {");
		interfaceDef.append(sNewLine);

		interfaceDef.append("\tbaseobject \"");
		interfaceDef.append(fBaseObject);
		interfaceDef.append("\" in ");
		interfaceDef.append(fTableName);
		interfaceDef.append("(");
		interfaceDef.append(fBaseObjectColumn);
		interfaceDef.append(");");
		interfaceDef.append(sNewLine);

		for (String attribute : fAttributeList.keySet())
		{
			String columnName = fAttributeList.get(attribute);
			interfaceDef.append("\tattribute \"");
			interfaceDef.append(attribute);
			interfaceDef.append("\" ");
			interfaceDef.append(fTableName);
			interfaceDef.append("(");
			interfaceDef.append(columnName);
			interfaceDef.append(");");
			interfaceDef.append(sNewLine);
		}

		interfaceDef.append("}");
		interfaceDef.append(sNewLine);

		return interfaceDef.toString();
	}

	@Override
	public String getObjectName()
	{
		return fInterfaceName;
	}

	@Override
	public Section getSectionType()
	{
		return Section.INTERFACE;
	}

	public String[] getAttributeNames()
	{
		return fAttributeList.keySet().toArray(new String[0]);
	}

	public String getAttributeColumn(String attribute)
	{
		return fAttributeList.get(attribute);

	}
	
	private void readObject(ObjectInputStream iStream) throws IOException, ClassNotFoundException
	{
		iStream.defaultReadObject();
		validateState();
	}
	
	private void validateState()
	{
		if(fAttributeList == null)
		{
			throw new IllegalArgumentException();
		}
		else if(fInterfaceName == null || fInterfaceName.isEmpty())
		{
			throw new IllegalArgumentException();
		}
		else if(fTableName == null)
		{
			throw new IllegalArgumentException();
		}
		else if(fBaseObject == null)
		{
			throw new IllegalArgumentException();
		}
		else if(fBaseObjectColumn == null)
		{
			throw new IllegalArgumentException();
		}
	}

	private void writeObject(ObjectOutputStream oStream) throws IOException
	{
		oStream.defaultWriteObject();
	}
}
